#include "NRF24/NRF.h"

// 2G4通信地址
//------------------------------------------------------------------------------------------		
// const uint8_t RF2G4_ADDR_TX[5] ={0x34,0x43,0x10,0x10,0x01};		// 0X6A,0X69,0X78,0X69,0X6E
// const uint8_t RF2G4_ADDR_RX[5] ={0x34,0x43,0x10,0x10,0x01};		// ASCII：jixin

const uint8_t RF2G4_ADDR_TX[5] ={0x0A,0x01,0x07,0x0E,0x01};		// 0X6A,0X69,0X78,0X69,0X6E
const uint8_t RF2G4_ADDR_RX[5] ={0x0A,0x01,0x07,0x0E,0x01};		// ASCII：jixin
//------------------------------------------------------------------------------------------

uint8_t RF2G4_Send_Data[14] = { 0 };		// 2.4G发射数据缓存数组
			 
uint8_t RF2G4_Receive_Data[14] = { 0 };	// 2.4G接收数据缓存数组


void W_SPI_CE(uint8_t vlaue)
{
    if(vlaue) HAL_GPIO_WritePin(SPI_Port,RF2G4_CE,GPIO_PIN_SET);
    else HAL_GPIO_WritePin(SPI_Port,RF2G4_CE,GPIO_PIN_RESET);
}
void W_SPI_CSN(uint8_t vlaue)
{
    if(vlaue) HAL_GPIO_WritePin(SPI_Port,RF2G4_CSN,GPIO_PIN_SET);
    else HAL_GPIO_WritePin(SPI_Port,RF2G4_CSN,GPIO_PIN_RESET);
}
uint8_t R_SPI_IRQ(void)
{
    return HAL_GPIO_ReadPin(SPI_Port,RF2G4_CSN);
}

// 设置SPI速度
//---------------------------------------------------
// SPI_DivideFrequency_2	2分频： 18MHz
// SPI_DivideFrequency_4	4分频： 9MHz
// SPI_DivideFrequency_8	8分频： 4.5MHz
// SPI_DivideFrequency_16	16分频：2.25MHz
void SPI2_SetSpeed(uint8_t SPI_DivideFrequency)
{
	SPI2->CR1&=0XFFC7;
	SPI2->CR1|=SPI_DivideFrequency;	//设置SPI2速度 
	//SPI_Cmd(SPI2,ENABLE); 
} 
//---------------------------------------------------


// // SPI读写一个字节
// // TxData:要写入的字节
// // 返回值:读取到的字节
// //-----------------------------------------------------------------------
// uint8_t SPI2_ReadWriteByte(uint8_t TxData)
// {		
// 	uint8_t TxWait = 0;
// 	uint8_t RxWait = 0;
	
// 	// 等待发送缓存为空
// 	while(SPI_I2S_GetFlagStatus(SPI2, SPI_FLAG_TXE) == RESET)
// 	{
// 		TxWait++;
// 		if(TxWait>250)	// 等待时间过长则放弃本次读写
// 		return 0;
// 	}	

// 	SPI_I2S_SendData(SPI2, TxData); // SPI2写一个字节
	
// 	// 等待接收缓存为空
// 	while (SPI_I2S_GetFlagStatus(SPI2, SPI_FLAG_RXNE) == RESET)
// 	{
// 		RxWait++;
// 		if(RxWait>250)	// 等待时间过长则放弃本次读写
// 		return 0;
// 	}	  	
	
// 	return SPI_I2S_ReceiveData(SPI2); // 将读到的字节返回					    
// }
// //-----------------------------------------------------------------------

// SPI读写一个字节
// TxData:要写入的字节
// 返回值:读取到的字节
//-----------------------------------------------------------------------
uint8_t SPI2_ReadWriteByte(uint8_t TxData)
{
    uint8_t RxData = 0;  // 用于存储接收到的数据
    uint16_t Timeout = 250;  // 超时计数器

    // 使用 HAL_SPI_TransmitReceive 函数发送和接收数据
    if (HAL_SPI_TransmitReceive(&hspi2, &TxData, &RxData, 1, Timeout) != HAL_OK)
    {
        // 如果传输失败，返回0
        return 0;
    }

    // 返回接收到的数据
    return RxData;
}
//-----------------------------------------------------------------------


// 2G4的SPI读写
//==========================================================================================

// 写寄存器命令
void nrf24_write_register(uint8_t reg, uint8_t value)
{
    W_SPI_CSN(0); 
    HAL_SPI_Transmit(&hspi2, &reg, 1, HAL_MAX_DELAY);
    HAL_SPI_Transmit(&hspi2, &value, 1, HAL_MAX_DELAY);
    W_SPI_CSN(1); 
}

// 读寄存器命令
uint8_t nrf24_read_register(uint8_t reg)
{
    uint8_t value;
    W_SPI_CSN(0); 
    HAL_SPI_Transmit(&hspi2, &reg, 1, HAL_MAX_DELAY);
    HAL_SPI_Receive(&hspi2, &value, 1, HAL_MAX_DELAY);
    W_SPI_CSN(1); 
    return value;
}

// SPI对SI24R1寄存器的写操作
// Reg 			= 寄存器
// Write_Value 	= 写入的值
// return		= 状态值
//--------------------------------------------------------
uint8_t RF2G4_Write_Reg(uint8_t Reg,uint8_t Write_Value)
{
	uint8_t V_Reg;	
	
	W_SPI_CSN(0);                 		// 使能SPI传输
	
  	V_Reg =SPI2_ReadWriteByte(Reg);		// 发送寄存器号 
	
  	SPI2_ReadWriteByte(Write_Value);	// 写入寄存器的值
	
  	W_SPI_CSN(1);                 		// 禁止SPI传输	 
	
  	return(V_Reg);       				// 返回状态值
}
//--------------------------------------------------------

// 向寄存器中写入指定长度的数据
// Reg		= 寄存器
// P_Data 	= 数据指针
// N_Data 	= 数据个数
// return 	= 此次读到的状态寄存器值
//--------------------------------------------------------
uint8_t RF2G4_Write_Cont(uint8_t Reg, uint8_t* P_Data, uint8_t N_Data)
{
	uint8_t V_Reg = 0;
	uint8_t C_Write = 0;
	
	W_SPI_CSN(0);          			// 使能SPI传输
	
  	V_Reg = SPI2_ReadWriteByte(Reg);	// 选定寄存器,并读取状态值
	
  	for(; C_Write<N_Data; C_Write++)
	{
		SPI2_ReadWriteByte(*P_Data++); 	// 写入数据
	}
		 
	W_SPI_CSN(1);       				// 关闭SPI传输
	
  	return V_Reg;          				// 返回读到的状态值
}
//--------------------------------------------------------



// SPI对SI24R1寄存器的读操作
// Reg 		= 寄存器
// return 	= 写入的值
//--------------------------------------------------------
uint8_t RF2G4_Read_Reg(uint8_t Reg)
{
	uint8_t V_Reg;	    
	
	W_SPI_CSN(0);          			// 使能SPI传输		
	
  	SPI2_ReadWriteByte(Reg);   			// 发送寄存器号
	
  	V_Reg=SPI2_ReadWriteByte(0xFF);		// 读取寄存器内容
	
  	W_SPI_CSN(1);          			// 禁止SPI传输		    
	
  	return(V_Reg);           			// 返回状态值
}	
//--------------------------------------------------------



// 从寄存器中读出指定长度的数据
// Reg = 寄存器(位置)
// P_Data = 数据指针
// N_Data = 数据个数
// return = 此次读到的状态寄存器值
//----------------------------------------------------------------------------
uint8_t RF2G4_Read_Cont(uint8_t Reg, uint8_t* P_Data, uint8_t N_Data)
{
	uint8_t V_Reg;
	uint8_t C_Read = 0;	
	
	W_SPI_CSN(0);           			// 使能SPI传输
	
  	V_Reg=SPI2_ReadWriteByte(Reg);		// 发送寄存器值(位置),并读取状态值
	
 	for(; C_Read<N_Data;C_Read++)
	
	P_Data[C_Read] = SPI2_ReadWriteByte(0xFF);	// 读出数据

	W_SPI_CSN(1);       				// 关闭SPI传输
	
  	return V_Reg;        				// 返回读到的状态值
}
//----------------------------------------------------------------------------
//==========================================================================================			   


// 检测SI24R1是否正常
// return = 0:成功,	1:失败
//---------------------------------------------------------------------------------------------------
uint8_t RF2G4_Check(void)
{
	uint8_t Array_Test[5]={0X66,0X66,0X66,0X66,0X66};
	uint8_t C_Test = 0;
	
	SPI2_SetSpeed(SPI_BAUDRATEPRESCALER_4); 			// SPI速度为9Mhz（SI24R1的最大SPI时钟为10Mhz）
	
	RF2G4_Write_Cont(W_REGISTER+TX_ADDR,Array_Test,5);	// 写入5个字节的地址.	
	
	RF2G4_Read_Cont(TX_ADDR,Array_Test,5); 				// 读出写入的地址  
	
	for(; C_Test<5; C_Test++)
	if(Array_Test[C_Test]!=0X66)
		break;
	
	if(C_Test!=5)return 1;		// SI24R1错误	
	
	return 0;		 			// SI24R1正确
}
//---------------------------------------------------------------------------------------------------



// 初始化SI24R1为接收模式
//-----------------------------------------------------------------------------------------------------------
void RF2G4_RX_Mode(void)
{
	W_SPI_CE(0);	  
  	RF2G4_Write_Cont(W_REGISTER+RX_ADDR_P0, (uint8_t*)RF2G4_ADDR_RX, RX_ADR_WIDTH);	// 设置RX节点地址
	  
  	RF2G4_Write_Reg(W_REGISTER+EN_AA,0x01);    		// 使能通道0的自动应答
  	RF2G4_Write_Reg(W_REGISTER+EN_RXADDR,0x01);		// 使能通道0的接收地址
  	RF2G4_Write_Reg(W_REGISTER+RF_CH,40);	     	// 设置RF通信频率
  	RF2G4_Write_Reg(W_REGISTER+RX_PW_P0,14);		// 设置通道0的有效数据宽度（14位）
  	RF2G4_Write_Reg(W_REGISTER+RF_SETUP,0x27);		// 设置:发射功率7dBm、射频数据率250kbps
  	RF2G4_Write_Reg(W_REGISTER+CONFIG, 0x0F);		// 配置参数;接收模式、开机模式、CRC=2Byte、开启CRC、。。。
  	W_SPI_CE(1); 	// CE为高,进入接收模式 
}					
//-----------------------------------------------------------------------------------------------------------

// 初始化SI24R1为发射模式
//-------------------------------------------------------------------------------------------------------------------
void RF2G4_TX_Mode(void)
{														 
	W_SPI_CE(0);	    
  	RF2G4_Write_Cont(W_REGISTER+TX_ADDR,(uint8_t*)RF2G4_ADDR_TX,TX_ADR_WIDTH);		// 设置TX节点地址
  	RF2G4_Write_Cont(W_REGISTER+RX_ADDR_P0,(uint8_t*)RF2G4_ADDR_RX,RX_ADR_WIDTH); 	// 设置RX节点地址（ACK）	  

  	RF2G4_Write_Reg(W_REGISTER+EN_AA,0x01);     	// 使能通道0的自动应答    
  	RF2G4_Write_Reg(W_REGISTER+EN_RXADDR,0x01); 	// 使能通道0的接收地址  
  	RF2G4_Write_Reg(W_REGISTER+SETUP_RETR,0x1A);	// 设置自动重发间隔时间:500us + 86us;最大自动重发次数:10次
  	RF2G4_Write_Reg(W_REGISTER+RF_CH,40);       	// 设置RF通信频率
  	RF2G4_Write_Reg(W_REGISTER+RF_SETUP,0x27);  	// 设置:发射功率7dBm、射频数据率250kbps  
  	RF2G4_Write_Reg(W_REGISTER+CONFIG,0x0E);    	// 配置参数;接收模式、开机模式、CRC=2Byte、开启CRC、。。。
	  W_SPI_CE(1);	//CE为高,10us后启动发送
}
//-------------------------------------------------------------------------------------------------------------------



// SI24R1发送一帧数据
// P_Data	= 待发送数据首地址
// N_Data	= 待发送数据的个数
// return	= 发送完成状况
//-------------------------------------------------------------------------------------------
uint8_t RF2G4_Tx_Packet(uint8_t* P_Data,uint8_t N_Data)
{
	uint8_t V_Reg;
	
 	SPI2_SetSpeed(SPI_BAUDRATEPRESCALER_4);	// SPI速度为9Mhz（24L01的最大SPI时钟为10Mhz）   
	
	 W_SPI_CE(0);
	
  	RF2G4_Write_Cont(W_TX_PAYLOAD,P_Data,N_Data);	// 将要发送的数据写入发送缓存器
	
	  W_SPI_CE(1);			// 启动发送	   
	
	while(RF2G4_IRQ != 0);	// 等待发送完成
	
	V_Reg = RF2G4_Read_Reg(STATUS);  // 读取状态寄存器的值	   
	
	RF2G4_Write_Reg(W_REGISTER+STATUS,V_Reg); 	// 清除TX_DS/MAX_RT中断标志
	
	
	if(V_Reg & TX_MAX)	// 判断是否达到最大重发次数
	{
		RF2G4_Write_Reg(FLUSH_TX,0xFF);	// 清除TX_FIFO 
		
		return TX_FAIL_MAX; 	// 返回发送失败（达到最大重发次数）
	}
	
	if(V_Reg & TX_OK)	
	{
		return TX_SUCCESS;		// 返回发送成功
	}

	return 0xFF;				// 返回发送失败
}
//-------------------------------------------------------------------------------------------


// SI24R1接收一帧数据
// P_Data	= 缓存接收数据的首地址
// N_Data	= 待缓存数据的个数
// return	= 数据接收情况
//-------------------------------------------------------------------------------------------
uint8_t RF2G4_Rx_Packet(uint8_t* P_Data,uint8_t N_Data)
{
	uint8_t V_Reg;		    							   
	SPI2_SetSpeed(SPI_BAUDRATEPRESCALER_4); 	// SPI速度为9Mhz（SI24R1的最大SPI时钟为10Mhz）   
	
	V_Reg=RF2G4_Read_Reg(STATUS);  				// 读取状态寄存器的值    	 
	
	RF2G4_Write_Reg(W_REGISTER+STATUS,V_Reg); 	// 清除TX_DS/MAX_RT中断标志
	
	if(V_Reg & RX_OK)		// 判断是否接收到数据
	{
		RF2G4_Read_Cont(R_RX_PAYLOAD,P_Data,N_Data);	// 读取数据
		
		RF2G4_Write_Reg(FLUSH_RX,0xFF);					// 清除RX_FIFO 
		
		return RX_SUCCESS; 	// 返回接收成功
	}	  
	
	return RX_FAIL;			// 返回接收失败
}
//-------------------------------------------------------------------------------------------


// RF2G4初始化
//------------------------------------------------------------------------------------------
void RF2G4_Init(void)
{
 
	// 初始化硬件接口
    // HAL_Delay(100);  // 延时等待模块稳定

    // // 配置寄存器
    // nrf24_write_register(0x00, 0x0E);  // CONFIG: 接收模式，CRC 使能
    // nrf24_write_register(0x01, 0x3F);  // EN_AA: 使能自动应答
    // nrf24_write_register(0x02, 0x03);  // EN_RXADDR: 接收通道 0 和 1 使能
    // nrf24_write_register(0x03, 0x03);  // SETUP_AW: 地址宽度为 5 字节
    // nrf24_write_register(0x04, 0x03);  // SETUP_RETR: 自动重发次数和延迟
    // nrf24_write_register(0x05, 0x02);  // RF_CH: 设置频道
    // nrf24_write_register(0x06, 0x0F);  // RF_SETUP: 设置发射功率和数据速率
    // nrf24_write_register(0x07, 0x70);  // STATUS: 清除中断标志

	SPI2_ReadWriteByte(0xFF);

	W_SPI_CE(0); 			// 使能SI24R1
	
	W_SPI_CSN(1);			// SPI片选取消  
	
}	

//------------------------------------------------------------------------------------------	 	 

